/*
 	Tool for Path Finding Algorithm Testing (ToPFAT) 
 	
    Copyright (C) 2009, Teemu Turunen and Arttu Viljakainen 
    Published under GNU General Public License V3 
    (see http://www.gnu.org/licenses/licenses.html)
    
    This file is part of Tool for Path Finding Algorithm Testing.

    Tool for Path Finding Algorithm Testing is free software: you can 
    redistribute it and/or modify it under the terms of the GNU General 
    Public License as published by the Free Software Foundation, 
    either version 3 of the License, or (at your option) any later version.

    Tool for Path Finding Algorithm Testing is distributed in the hope that it
    will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 
    Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Tool for Path Finding Algorithm Testing. If not, see         <http://www.gnu.org/licenses/>.
 */

package pathfinding.gui;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;

import pathfinding.CellTerrainType;
import pathfinding.IconStore;
import pathfinding.gui.listeners.MouseInput;

/**
 * Class to represent cells of the map.
 * 
 * @author arttu viljakainen
 *
 */
public class MapCell extends JLabel {

	public Color mouseOverBgColor;
	public Color colorWhenNotMouseOver;
	private CellTerrainType cellTerrainType;
	private Icon labelIcon;
	private CellIkonType cellIkonType;
	
	private Point location;

	public enum CellIkonType {
		START,
		GOAL,
		NOTHING,
		UNUSED_CANDIDATE,
		USED_CANDIDATE,
		PATH_CELL;
	}
	
	/**
	 * 
	 * @param terrainType
	 * @param point
	 */
	public MapCell(CellTerrainType terrainType, Point point) {
		setCellTerrainType(terrainType);
		cellIkonType = CellIkonType.NOTHING;
		
		this.location = point;
		this.setOpaque(true);
		this.addMouseListener(MouseInput.getInstance());
		this.addMouseMotionListener(MouseInput.getInstance());
		this.setVerticalAlignment(CENTER);
		this.setHorizontalAlignment(CENTER);
	}
		
	/**
	 * Set the terrain type of the cell (Wall, Floor).
	 * @param terrainType
	 */
	public void setCellTerrainType(CellTerrainType terrainType) {
		this.cellTerrainType = terrainType;
		switch(terrainType) {
		case FLOOR:
			this.mouseOverBgColor = Color.LIGHT_GRAY;
			this.colorWhenNotMouseOver = Color.GRAY;
			break;
		case WALL:
			this.mouseOverBgColor = Color.BLUE;
			this.colorWhenNotMouseOver = Color.BLACK;
			break;
		}
		setBackground(colorWhenNotMouseOver);
		validate();
	}

	/**
	 * 
	 * @return True if walkable.
	 */
	public boolean isWalkable() {
		return cellTerrainType.isWalkable();
	}

	/**
	 * 
	 * @return Cost of cell.
	 */
	public int getCost() {
		return 1;
	}
	
	public void setStartCell() {
		setCellIcon(CellIkonType.START);
	}
	
	public void setGoalCell() {
		setCellIcon(CellIkonType.GOAL);
	}
	
	public void setNothingCell() {
		setCellIcon(CellIkonType.NOTHING);
		setToolTip("");
	}
	
	public void setUnusedCandidateCell() {
		setCellIcon(CellIkonType.UNUSED_CANDIDATE);
	}
	
	public void setUsedCandidateCell() {
		setCellIcon(CellIkonType.USED_CANDIDATE);
	}
	
	public void setPathCell() {
		setCellIcon(CellIkonType.PATH_CELL);
	}
	
	/**
	 * 
	 * @param cellIkonType
	 */
	private void setCellIcon(CellIkonType cellIkonType) {
		this.cellIkonType = cellIkonType;
		switch(cellIkonType) {
		case START:
			setIcon(IconStore.getInstance().getStartIcon());
			break;
		case GOAL:
			setIcon(IconStore.getInstance().getGoalIcon());
			break;
		case NOTHING:
			setIcon(null);
			break;
		case UNUSED_CANDIDATE:
			setIcon(IconStore.getInstance().getAlgorithmUnusedCandidateIcon());
			break;
		case USED_CANDIDATE:
			setIcon(IconStore.getInstance().getAlgorithmUsedCandidateIcon());
			break;
		case PATH_CELL:
			setIcon(IconStore.getInstance().getAlgorithmSelectedPathIcon());
			break;
		}
		
		this.setToolTipForStartAndGoal();
		this.repaint();
	}
	
	public Point getPoint() {
		return location;
	}
	
	@Override
	public void setIcon(Icon icon) {
		labelIcon = icon;
	}
	
    @Override
	public void paintComponent(Graphics g) {

		super.paintComponent(g);
		
		if (this.labelIcon != null && this.labelIcon.getIconWidth() > 0
				&& this.labelIcon.getIconHeight() > 0) {
			g.drawImage(((ImageIcon)this.labelIcon).getImage(), 0, 0, 
					this.getWidth(), this.getHeight(), null);
		}

	}
	
    private void setToolTipForStartAndGoal() {
    	String tipText = "";
    	switch (this.cellIkonType) {
    	case START:
    		tipText = "Start cell";
			break;
		case GOAL:
			tipText = "Goal cell";
			break;
		}
    	
    	if (tipText.length() > 0)
    		this.setToolTipText(tipText);
    	else
    		this.setToolTipText(null);
    }
    
    public void setToolTip(String tipText) {
    	if (tipText.length() > 0)
    		this.setToolTipText(tipText);
    	else
    		this.setToolTipText(null);
    }
    
    public Object clone() {
    	MapCell clone = new MapCell(this.cellTerrainType, new Point(this.location));
    	clone.mouseOverBgColor = this.mouseOverBgColor;
    	clone.colorWhenNotMouseOver = this.colorWhenNotMouseOver;
    	clone.setToolTipText(this.getToolTipText());
    	return clone;
    }
    
    public Point getLocation() {
    	return location;
    }
    
}
